package com.skiving.cloud.file.controller;

import com.mybatisflex.core.paginate.Page;
import com.skiving.cloud.auth.entity.AuthUser;
import com.skiving.cloud.auth.entity.FileInputStreamVo;
import com.skiving.cloud.auth.logutils.OperateLog;
import com.skiving.cloud.auth.util.UserUtil;
import com.skiving.cloud.common.utils.PageParameter;
import com.skiving.cloud.common.utils.ReturnT;
import com.skiving.cloud.common.utils.UuidUtil;
import jodd.io.FileNameUtil;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.UploadedFile;
import org.noear.solon.core.util.MimeType;
import com.skiving.cloud.file.entity.SysFile;
import com.skiving.cloud.file.service.SysFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;

/**
 * 附件 控制层。
 *
 * @author skivingcloud
 * @since 2025-03-14
 */
@Slf4j
@Controller
@Api("附件接口")
@Mapping("/sysFile")
@Produces(MimeType.APPLICATION_JSON_UTF8_VALUE)
public class SysFileController {

    @Inject
    private SysFileService sysFileService;

    /**
     * 添加附件。
     *
     * @param sysFile 附件
     * @return {@code true} 添加成功，{@code false} 添加失败
     */
    @Post
    @Mapping("/save")
    @ApiOperation("保存附件")
    @OperateLog(module="文件管理", description = "新增文件")
    public ReturnT<Boolean> save(@Body @ApiParam("附件") SysFile sysFile) {
        sysFile.setId(UuidUtil.get32UUID());
        return ReturnT.ok(sysFileService.save(sysFile));
    }

    /**
     * 根据主键删除附件。
     *
     * @param id 主键
     * @return {@code true} 删除成功，{@code false} 删除失败
     */
    @Get
    @Mapping("/remove/{id}")
    @ApiOperation("根据主键附件")
    @OperateLog(module="文件管理", description = "删除文件")
    public ReturnT<Boolean> remove(@Path @ApiParam("附件主键") String id) {
        return ReturnT.ok(sysFileService.removeById(id));
    }

    /**
     * 根据主键更新附件。
     *
     * @param sysFile 附件
     * @return {@code true} 更新成功，{@code false} 更新失败
     */
    @Post
    @Mapping("/update")
    @ApiOperation("根据主键更新附件")
    @OperateLog(module="文件管理", description = "修改文件")
    public ReturnT<Boolean> update(@Body @ApiParam("附件主键") SysFile sysFile) {
        return ReturnT.ok(sysFileService.updateById(sysFile, true));
    }

    /**
     * 查询所有附件。
     *
     * @return 所有数据
     */
    @Get
    @Mapping("/list")
    @ApiOperation("查询所有附件")
    public ReturnT<List<SysFile>> list() {
        return ReturnT.ok(sysFileService.list());
    }

    /**
     * 根据附件主键获取详细信息。
     *
     * @param id 附件主键
     * @return 附件详情
     */
    @Get
    @Mapping("/getInfo/{id}")
    @ApiOperation("根据主键获取附件")
    public ReturnT<SysFile> getInfo(@Path @ApiParam("附件主键") String id) {
        return ReturnT.ok(sysFileService.getById(id));
    }

    /**
     * 分页查询附件。
     *
     * @param parameter 分页对象
     * @return 分页对象
     */
    @Post
    @Mapping("/page")
    @ApiOperation("分页查询附件")
    public ReturnT<Page<SysFile>> page(@Body @ApiParam("分页信息") PageParameter<SysFile> parameter) {
        return ReturnT.ok(sysFileService.queryByPage(parameter));
    }

    /**
     * 文件上传，使用formData.append('file', val.raw)来上传文件
     *
     * @param ctx 请求参数
     * @return 上传结果
     */
    @Post
    @Mapping(path = "/importCommon", multipart=true)
    @ApiOperation("文件上传")
    @OperateLog(module="文件管理", description = "文件上传")
    public ReturnT<List<String>> importCommon(Context ctx) {
        try {
            AuthUser user = UserUtil.getCurrentUser();
            UploadedFile[] files= ctx.fileValues("file");
            String businessId = ctx.param("businessId");
            String belongModule = ctx.param("belongModule");//模块
            List<String> fileIds = sysFileService.saveFiles(files, businessId, user, belongModule);
            return ReturnT.ok(fileIds);
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return ReturnT.error("上传文件失败");
        }
    }

    /**
     * 文件下载
     *
     * @param id       文件记录id
     * @param ctx 返回
     */
    @Mapping("/downloadFile/{id}")
    @ApiOperation("文件下载")
    public void downloadFile(@Path("id") String id, Context ctx) {
        SysFile fileManagement = sysFileService.getById(id);
        try{
            sysFileService.downloadFile(fileManagement, ctx);
        }catch(Exception e){
            log.error("下载文件失败", e);
        }
    }

    /**
     * 根据业务ID查询附件信息
     * @param businessId 业务ID
     * @return 附件信息
     */
    @Get
    @Mapping("/getFileListByBusinessId/{businessId}")
    @ApiOperation("根据业务ID查询附件信息")
    public ReturnT<List<SysFile>> getFileListByBusinessId(@Path("businessId") String businessId) {
        return ReturnT.ok(sysFileService.getFileListByBusId(businessId));
    }

    /**
     * 文件上传，使用formData.append('file', val.raw)来上传文件
     *
     * @param fileInputStreamVo 文件流
     * @return 上传结果
     */
    @Post
    @Mapping("/importInputStream")
    @OperateLog(module="文件管理", description = "文件上传")
    public ReturnT<String> importInputStream(@Body FileInputStreamVo fileInputStreamVo) {
        try {
            String fileId = sysFileService.saveFileInputStream(fileInputStreamVo.getInputStream(),
                    fileInputStreamVo.getBusinessId(), fileInputStreamVo.getUserId(),
                    fileInputStreamVo.getBelongModule(),
                    fileInputStreamVo.getFileName(), FileNameUtil.getExtension(fileInputStreamVo.getFileName()));
            return ReturnT.ok(fileId);
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return ReturnT.error("上传文件失败");
        }
    }
}
